/******************************************************************************
 * Copyright (C) 2014 ShenZhen YiHua Computer Co., Ltd.
 * All Rights Reserved.
 * 本软件为深圳怡化电脑股份有限公司开发研制。未经本公司正式书面同意，其他任何个人、团体
 * 不得使用、复制、修改或发布本软件.
 *****************************************************************************/
package net.dgg.dggcloud.core.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
  * @ClassName: ObjectArraySorter
  * @Description: 传入一个对象数组，一个排序的根据(对象的某个属性)，一个布尔值(是否逆序) ，使用sort方法之后返回一个排序之后的对象数组
  * @date 2013年8月31日 下午12:24:19
  * @Author 唐先杰
 */
@SuppressWarnings({"rawtypes","unchecked","static-access"})
public class ObjectArraySorter {
	private List<Object> objArray;
	private String sortBy;
	private boolean desc;

	public ObjectArraySorter(List objArray, String sortBy, boolean desc) {
		this.objArray = objArray;
		this.sortBy = sortBy;
		this.desc = desc;
	}
	//返回一个排序之后的对象list
	public List sort() {
		Object[] objA = objArray.toArray();

		MyComparator c = new MyComparator(objArray.get(0).getClass().getName(),
				sortBy, desc);
		Arrays.sort(objA, c);
		List l2 = Arrays.asList(objA);
		return l2;
	}

	class MyComparator implements Comparator {
		private String className;// 要被比较的类
		private String sortBy;// 排序的属性
		private boolean desc = false;// 是否逆序

		/**
		 * 
		 * @param className 要被比较的类
		 * @param sortBy 根据哪个属性进行排序
		 * @param desc 是否逆序
		 */
		public MyComparator(String className, String sortBy, boolean desc) {
			this.className = className;
			this.sortBy = sortBy;
			this.desc = desc;
		}

		public int compare(Object o1, Object o2) {
			try {
				// 拿到className对应的类
				Class x = Class.forName(className);

				// 将参数中2个对象强转为这个类的对象
				Object x1 = x.cast(o1);
				Object x2 = x.cast(o2);

				// 拿到要被排序的属性
				Field f = x.getDeclaredField(sortBy);

				String getMethod = "get";
				String n = f.getName();
				Character xxx = n.charAt(0);

				Character xx2 = xxx.toUpperCase(xxx);
				String newStr = getMethod + xx2 + f.getName().substring(1);

				Method m = x.getMethod(newStr, new Class[] {});
				Object getFieldValue1 = m.invoke(x1, new Object[] {});// 拿到了o1对象的这个属性值
				Object getFieldValue2 = m.invoke(x2, new Object[] {});// 拿到了o2对象的这个属性值

				// 判断这个类的类型
				if (f.getType().getName().equalsIgnoreCase("java.lang.Integer")
						|| f.getType().getName().equalsIgnoreCase(
								"java.lang.Double")
						|| f.getType().getName().equalsIgnoreCase("java.lang.Long")) { // 如果是数字类,直接返回值之差

					if (!desc)
						return (Integer) getFieldValue1 - (Integer) getFieldValue2;
					else
						return (Integer) getFieldValue2 - (Integer) getFieldValue1;

				}else if (f.getType().getName()
								.equalsIgnoreCase("java.lang.Float")) { // 如果是数字类,直接返回值之差
					Float f1 = getFieldValue1 == null?0:(Float)getFieldValue1;
					Float f2 = getFieldValue2 == null?0:(Float)getFieldValue2;

					if (!desc){
						if (f1 - f2 == 0) {
							return 0 ;
						}else if (f1-f2>0) {
							return 1;
						}
						return -1;
					}
					else{
						if (f1 - f2 == 0) {
							return 0 ;
						}else if (f1-f2>0) {
							return -1;
						}
						return 1;
					}

				}else if (f.getType().getName().equalsIgnoreCase("java.util.Date")) {// 如果是日期类,返回日期的毫秒值之差
					Date date1 = (Date) getFieldValue1;
					Date date2 = (Date) getFieldValue2;

					Long l1 = date1.getTime();
					Long l2 = date2.getTime();

					if (!desc){
						if (l1 - l2 == 0) {
							return 0;
						}
						return l1 - l2 > 0 ? 1 : -1;
					}
					else{
						if (l1 - l2 == 0) {
							return 0;
						}
						return l1 - l2 > 0 ? -1 : 1;
					}
				} else if (f.getType().getName().equalsIgnoreCase(
						"java.lang.String")) {// 如果是字符串，按照字符串的比较规则进行比较
					String str1 = (String) getFieldValue1;
					String str2 = (String) getFieldValue2;
					int index = 0;
					// 首先应该比较字符串的长度,如果第一个比第二个长，则以第一个为准进行循环比较,反之以第二个为准
					int length = (str1.length() > str2.length()) ? str1.length()
							: str2.length();
					// 从第一个字符开始比较其ASIC码，如果相同继续往下，如果不同直接返回差值
					while (index < length) {
						if (str1.charAt(index) == str2.charAt(index)) {
							index++;
							continue;
						} else {
							try {
								if (!desc)
									return str1.charAt(index) - str2.charAt(index) > 0 ? 1
											: -1;
								else
									return str1.charAt(index) - str2.charAt(index) > 0 ? -1
											: 1;
							} catch (NullPointerException e) {// 在这里只可能是短的字符串出现空指针异常
								// 短的排在前面
								if (!desc)
									return -1;
								else
									return 1;
							}
						}
					}
				}

			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
			return 0;
		}
		
	}
	
	/**
	 * 
	 * @Title 
	 * @Description: 传入一个Integer对象List，排序
	 * 
	 * @param strList
	 * @param ascOrDesc
	 */
	public static void sortIntegerList(List<Integer> strList,boolean ascOrDesc) { 
		Integer[] array = new Integer[strList.size()];
		for(int i=0;i<strList.size();i++){
			array[i] = strList.get(i);
		}		
        int length = array.length;
        Integer temp; 
        boolean isSort; 
        for(int i = 1; i < length; i++) { 
            isSort = false; 
            for(int j = 0; j < length - i; j++) { 
            	
            	if(ascOrDesc){
	            	if(array[j]>array[j+1]){
	                    temp = array[j]; 
	                    array[j] = array[j+1]; 
	                    array[j+1] = temp; 
	                    isSort = true; 
	                }
            	}else{
            		if(array[j]<array[j+1]){
	                    temp = array[j]; 
	                    array[j] = array[j+1]; 
	                    array[j+1] = temp; 
	                    isSort = true; 
	                }
            	}
            } 
            if(!isSort) break; //如果没有发生交换，则退出循环 
        } 
             
        strList.clear();
        for(int i=0;i<array.length;i++){        	
        	strList.add(array[i]);
		} 
    } 
}